package com.heepay.api;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.heepay.common.HttpUtil;
import com.heepay.common.SignEncrypt;
import com.heepay.common.Utils;
import com.heepay.request.BaseRequest;
import com.heepay.respone.BaseResponse;
import com.heepay.respone.SignResponse;
import lombok.Data;


import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

@Data
public abstract class AbstractHeepayClient implements HeepayClient {
    private String serverUrl;
    private String method;
    private String version;
    private String merchantId;
    private X509Certificate cert;
    private PrivateKey privateKey;
    private PublicKey heepayPublicKey;


    public AbstractHeepayClient(String serverUrl, String privateKeystr, String publicKeystr, String method, String version, String merchantId) throws Exception {
        this.serverUrl = serverUrl;
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        byte[] privateKeyPath = org.bouncycastle.util.encoders.Base64.decode(privateKeystr.getBytes());
        byte[] publicKeyPath = org.bouncycastle.util.encoders.Base64.decode(publicKeystr.getBytes());
        privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec((privateKeyPath)));
        heepayPublicKey = keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyPath));
        this.method = method;
        this.version = version;
        this.merchantId = merchantId;

    }


    public SignResponse submitSign(BaseRequest baseRequest) {
        BaseResponse response = doPost(baseRequest, true);
        SignResponse signResponse = new SignResponse();
        if (response.getData() != null) {
            signResponse = JSON.parseObject(response.getData(), SignResponse.class);
        }
        signResponse.setCode(response.getCode());
        signResponse.setMsg(response.getMsg());
        signResponse.setSub_code(response.getSub_code());
        signResponse.setSub_msg(response.getSub_msg());
        signResponse.setData(response.getData());
        signResponse.setSign(response.getSign());
        return signResponse;
    }


    private BaseResponse doPost(BaseRequest baseRequest, boolean flag) {
        SignEncrypt signEncrypt = new SignEncrypt();
        HttpUtil httpUtil = new HttpUtil();
        BaseResponse baseResponse = new BaseResponse();
        try {
            baseRequest.setMerch_id(merchantId);
            baseRequest.setVersion(version);
            baseRequest.setMethod(method);
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            baseRequest.setTimestamp(df.format(new Date()));
            Map<String, String> map = Utils.convertBeanNoneEmpty(baseRequest);
            String bizJson = Utils.coverMap2String(map);
            //签名
            String sign = signEncrypt.sign(bizJson, privateKey);
            baseRequest.setSign(sign);


            //bizContent加密
            String content = signEncrypt.encrypt(baseRequest.getBiz_content(), heepayPublicKey);
            baseRequest.setBiz_content(content);


            System.out.println("加密后------------------------------------------------------------------------>" + content);
            System.out.println();

            System.out.println("待签名------------------------------------------------------------------------>" + bizJson);
            System.out.println();

            System.out.println("签名后------------------------------------------------------------------------>" + sign);
            System.out.println();

            String res = httpUtil.sendJsonHttpPost(serverUrl, JSON.toJSONString(baseRequest));
            System.out.println("resq------------------------------------------------------------------------>" + JSON.toJSONString(baseRequest));
            System.out.println();

            System.out.println("resp------------------------------------------------------------------------>" + res);
            System.out.println();

            //解析response 取到data并解密
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode jsonNode = objectMapper.readTree(res);
            String data = jsonNode.get("data").asText();
            //decrypt为解密后的值
            String decrypt = signEncrypt.decrypt(data, privateKey);
            //继续解析解密后的值拿到sign_url
            JsonNode jsonNode1 = objectMapper.readTree(decrypt);
            String sign_url = jsonNode1.get("sign_url").asText();
            System.out.println("sign_url------------------------------------------------------------------------>" + sign_url);

        } catch (Exception e) {
            baseResponse.setCode("40004");
            baseResponse.setMsg("发送请求异常");
        }
        return baseResponse;
    }
}
